"""
股票估值分析智能体

基于财务数据和估值指标进行股票估值分析。
支持文本和JSON格式输出。
"""

from typing import Dict, Any, List, Optional, Union
from agents import BaseAgent, LLMConfig
from tools.stock_data_provider import stock_data_provider
from langchain_core.tools import Tool
import pandas as pd
import logging
import chainlit as cl
import json
import re


class StockValuationAnalysisAgent(BaseAgent):
    """股票估值分析智能体"""

    def __init__(self, llm_config: Optional[LLMConfig] = None):
        super().__init__(
            name="StockValuationAnalysisAgent",
            description="股票估值分析智能体，基于财务数据进行估值分析",
            llm_config=llm_config
        )

    def get_tools(self) -> List[Tool]:
        """获取估值分析所需的工具"""
        return [
            Tool(
                name="get_valuation_data",
                description="获取股票实时估值数据，包括PE、PB、PS、市值等估值指标",
                func=self._get_valuation_data
            ),
            Tool(
                name="calculate_valuation_ratios",
                description="获取财务数据并计算PE、PB、PEG等关键估值比率",
                func=self._calculate_valuation_ratios
            ),
            Tool(
                name="analyze_historical_valuation",
                description="获取并分析股票历史估值水平和分位数，评估当前估值是否合理",
                func=self._analyze_historical_valuation
            ),
            Tool(
                name="analyze_peer_comparison",
                description="获取行业数据并分析同业比较，评估相对估值水平",
                func=self._analyze_peer_comparison
            ),
            Tool(
                name="calculate_peg_ratio",
                description="获取财务和估值数据并计算PEG比率（市盈率相对盈利增长比）",
                func=self._calculate_peg_ratio
            ),
            Tool(
                name="assess_fair_value",
                description="获取财务数据并使用DCF模型评估股票公允价值",
                func=self._assess_fair_value_tool
            ),
            Tool(
                name="generate_valuation_signals",
                description="综合获取估值数据并生成投资信号和建议",
                func=self._generate_valuation_signals
            )
        ]

    def get_system_prompt(self) -> str:
        return """
        你是专业的股票估值分析智能体，基于财务数据和估值指标进行价值评估。

        分析框架：
        1. 估值指标计算：PE、PB、PS、PCF等核心指标
        2. 历史估值对比：相对历史分位数位置
        3. 同业相对估值：行业内横向比较
        4. 内在价值评估：DCF等模型估值
        5. 估值信号生成：综合估值判断

        输出要求：
        - 使用清晰的markdown格式
        - 各部分用emoji和标题区分
        - 数据展示要简洁明了
        - 分析逻辑要严谨合理
        - 结论要明确具体

        标准输出结构：
        ## 💰 估值指标
        - 核心估值比率数值
        - 相对历史位置

        ## 📊 估值水平评估
        - 当前估值所处区间
        - 估值合理性判断

        ## 🔍 同业比较
        - 行业内相对位置
        - 估值差异分析

        ## 🎯 估值结论
        - 整体估值判断
        - 投资建议
        - 风险提示

        ## ⭐ 估值面评分 (0-10)
        评分标准：
        - 10: 估值极度低估，安全边际巨大，强烈推荐
        - 8-9: 估值显著低估，具备较好投资价值
        - 6-7: 估值基本合理，投资价值一般
        - 4-5: 估值偏高，投资风险增加
        - 2-3: 估值显著高估，投资风险较大
        - 0-1: 估值极度高估，强烈建议回避

        最终评分：[X/10] - 评分理由

        分析原则：
        - 基于数据自主推理，不要依赖预设阈值
        - 考虑行业特征和公司成长阶段
        - 关注估值指标的历史分位数
        - 结合盈利质量和现金流分析
        - 估值分析需结合宏观经济环境

        重点关注数据的内在逻辑关系，结合行业特征进行合理估值判断。
        """

    async def _get_valuation_data(self, stock_code: str) -> str:
        """获取估值数据"""
        try:
            import logging
            logging.info(f"开始获取股票{stock_code}的估值数据")
            valuation_data = await stock_data_provider.get_stock_valuation_data(stock_code)
            logging.info(f"获取到的估值数据: {valuation_data}")

            if not valuation_data:
                logging.warning(f"无法获取股票{stock_code}的估值数据")
                return f"无法获取股票{stock_code}的估值数据"

            result = f"## 💰 估值指标\n\n"

            # 显示主要估值指标
            key_metrics = [
                ('市盈率', 'pe'),
                ('市净率', 'pb'),
                ('市销率', 'ps'),
                ('市现率', 'pcf'),
                ('总市值', 'total_mv'),
                ('流通市值', 'circ_mv')
            ]

            for name, key in key_metrics:
                if key in valuation_data:
                    value = valuation_data[key]
                    logging.debug(f"处理指标 {name} ({key}): {value}")
                    if isinstance(value, (int, float)):
                        if '率' in name:
                            result += f"- {name}: {value:.2f}\n"
                        else:
                            result += f"- {name}: {value:,.0f}\n"
                    else:
                        result += f"- {name}: {value}\n"

            result += "\n"
            logging.info(f"成功生成估值数据结果")
            return result

        except Exception as e:
            self.logger.error(f"获取估值数据失败: {e}")
            return f"获取估值数据失败: {e}"

    async def _calculate_valuation_ratios(self, stock_code: str) -> str:
        """计算估值比率"""
        try:
            import logging
            logging.info(f"开始计算股票{stock_code}的估值比率")

            # 获取基本面数据
            fundamental_data = await stock_data_provider.get_stock_fundamental_data(stock_code)
            logging.info(f"获取到的基本面数据: {fundamental_data}")

            if not fundamental_data:
                logging.warning(f"无法获取股票{stock_code}的基本面数据")
                return f"无法获取股票{stock_code}的基本面数据"

            result = f"## 📊 估值水平评估\n\n"

            # 尝试计算一些基础比率
            try:
                # 获取最新财务数据
                profit_data = fundamental_data.get('profit_data', [])
                balance_data = fundamental_data.get('balance_data', [])
                logging.debug(f"利润数据: {profit_data}")
                logging.debug(f"资产负债数据: {balance_data}")

                if profit_data and balance_data:
                    latest_profit = profit_data[0] if profit_data else {}
                    latest_balance = balance_data[0] if balance_data else {}

                    # 计算一些基础比率
                    total_assets = latest_balance.get('totalAssets', 0)
                    total_liability = latest_balance.get('totalLiability', 0)
                    net_profit = latest_profit.get('netProfit', 0)
                    logging.debug(f"总资产: {total_assets}, 总负债: {total_liability}, 净利润: {net_profit}")

                    if total_assets > 0:
                        debt_ratio = total_liability / total_assets
                        result += f"- 资产负债率: {debt_ratio:.2%}\n"

                    if net_profit and total_assets:
                        roa = net_profit / total_assets
                        result += f"- 总资产报酬率: {roa:.2%}\n"

                    # 获取估值数据供大模型推理
                    valuation_data = await stock_data_provider.get_stock_valuation_data(stock_code)
                    logging.info(f"获取到的估值数据: {valuation_data}")

                    if valuation_data:
                        pe = valuation_data.get('pe')
                        pb = valuation_data.get('pb')

                        result += f"\n- 当前市盈率: {pe:.2f}\n" if pe else ""
                        result += f"- 当前市净率: {pb:.2f}\n" if pb else ""

                        # 让大模型自主判断估值水平
                        result += "\n基于以上财务和估值数据，请进行估值水平评估。\n"

                else:
                    result += "财务数据不足，无法进行详细估值分析\n"

            except Exception as calc_error:
                self.logger.error(f"计算过程中出现错误: {calc_error}")
                result += f"计算过程中出现错误: {calc_error}\n"

            result += "\n"
            logging.info(f"成功生成估值比率分析结果")
            return result

        except Exception as e:
            self.logger.error(f"计算估值比率失败: {e}")
            return f"计算估值比率失败: {e}"

    async def _analyze_historical_valuation(self, stock_code: str) -> str:
        """分析历史估值水平"""
        try:
            import logging
            logging.info(f"开始分析股票{stock_code}的历史估值水平")

            result = f"## 📈 历史估值对比\n\n"

            # 获取历史估值数据（简化版，使用当前估值数据作为参考）
            valuation_data = await stock_data_provider.get_stock_valuation_data(stock_code)
            logging.info(f"获取到的估值数据: {valuation_data}")

            if not valuation_data:
                logging.warning(f"无法获取股票{stock_code}的估值数据")
                return f"无法获取股票{stock_code}的估值数据"

            # 当前估值水平
            current_pe = valuation_data.get('pe_ratio') or valuation_data.get('pe_ratio_ths')
            current_pb = valuation_data.get('pb_ratio') or valuation_data.get('pb_ratio_ths')
            logging.debug(f"当前PE: {current_pe}, 当前PB: {current_pb}")

            if current_pe or current_pb:
                result += "- 当前估值水平：\n"
                if current_pe:
                    result += f"  - PE: {float(current_pe):.2f}\n"
                if current_pb:
                    result += f"  - PB: {float(current_pb):.2f}\n"
                result += "\n"

            # 提供数据让大模型自主判断
            result += "- 历史估值分析：\n"
            result += "  - 考虑该股票所属行业的一般估值水平\n"
            result += "  - 分析当前估值是否处于历史合理区间\n"
            result += "  - 评估是否存在低估或高估的情况\n\n"

            logging.info(f"成功生成历史估值分析结果")
            return result

        except Exception as e:
            self.logger.error(f"历史估值分析失败: {e}")
            return f"历史估值分析失败: {e}"

    async def _calculate_peg_ratio(self, stock_code: str) -> str:
        """计算PEG比率"""
        try:
            import logging
            logging.info(f"开始计算股票{stock_code}的PEG比率")

            result = f"股票{stock_code} PEG比率分析：\n\n"

            # 获取估值数据
            valuation_data = await stock_data_provider.get_stock_valuation_data(stock_code)
            logging.info(f"获取到的估值数据: {valuation_data}")

            # 获取财务数据以计算增长率
            fundamental_data = await stock_data_provider.get_stock_fundamental_data(stock_code)
            logging.info(f"获取到的财务数据: {fundamental_data}")

            if not valuation_data or not fundamental_data:
                logging.warning("数据不足，无法计算PEG比率")
                return "数据不足，无法计算PEG比率"

            # 获取PE比率
            pe_ratio = valuation_data.get('pe_ratio') or valuation_data.get('pe_ratio_ths')
            logging.debug(f"PE比率: {pe_ratio}")

            if not pe_ratio or float(pe_ratio) <= 0:
                logging.warning("PE数据无效，无法计算PEG比率")
                return "PE数据无效，无法计算PEG比率"

            # 尝试获取增长率（简化：使用净利润增长率）
            try:
                import akshare as ak
                financial_data = ak.stock_financial_abstract_ths(symbol=stock_code)
                logging.info(f"从akshare获取的财务数据: {financial_data}")

                if not financial_data.empty and len(financial_data) >= 2:
                    latest_profit = financial_data.iloc[-1].get('净利润', 0)
                    prev_profit = financial_data.iloc[-2].get('净利润', 0)
                    logging.debug(f"最新净利润: {latest_profit}, 上一期净利润: {prev_profit}")

                    if latest_profit and prev_profit and latest_profit != 'False' and prev_profit != 'False':
                        # 处理单位
                        if '亿' in str(latest_profit):
                            curr_val = float(str(latest_profit).replace('亿', ''))
                        else:
                            curr_val = float(latest_profit)

                        if '亿' in str(prev_profit):
                            prev_val = float(str(prev_profit).replace('亿', ''))
                        else:
                            prev_val = float(prev_profit)

                        if prev_val > 0:
                            growth_rate = (curr_val - prev_val) / prev_val * 100
                            logging.debug(f"计算出的增长率: {growth_rate}%")

                            result += "📊 PEG计算：\n"
                            result += f"  PE比率: {float(pe_ratio):.2f}\n"
                            result += f"  净利润增长率: {growth_rate:.1f}%\n"

                            if growth_rate > 0:
                                peg_ratio = float(pe_ratio) / growth_rate
                                result += f"  PEG比率: {peg_ratio:.2f}\n\n"
                                logging.info(f"计算出的PEG比率: {peg_ratio}")

                                result += "🎯 PEG评估：\n"
                                if peg_ratio < 0.5:
                                    result += "  ✅ PEG < 0.5，严重低估\n"
                                    result += "  💡 极具投资价值，高成长低估值\n"
                                elif peg_ratio < 1.0:
                                    result += "  ✅ PEG < 1，估值合理偏低\n"
                                    result += "  💡 具有投资价值，成长性与估值匹配\n"
                                elif peg_ratio < 1.5:
                                    result += "  📊 PEG在1-1.5之间，估值合理\n"
                                    result += "  💡 估值相对公允\n"
                                elif peg_ratio < 2.0:
                                    result += "  ⚠️ PEG > 1.5，估值偏高\n"
                                    result += "  💡 成长性不足以支撑当前估值\n"
                                else:
                                    result += "  ❌ PEG > 2，估值过高\n"
                                    result += "  💡 明显高估，投资风险较大\n"

                                logging.info("成功生成PEG比率分析结果")
                                return result
                            else:
                                result += "  ⚠️ 净利润增长为负，PEG比率不适用\n"
                                logging.warning("净利润增长为负，PEG比率不适用")
                                return result

                logging.warning("增长率数据不足，无法计算PEG比率")
                return "增长率数据不足，无法计算PEG比率"

            except Exception as e:
                self.logger.error(f"计算PEG比率时出错: {e}")
                return f"计算PEG比率时出错: {e}"

        except Exception as e:
            self.logger.error(f"PEG比率分析失败: {e}")
            return f"PEG比率分析失败: {e}"

    async def _analyze_peer_comparison(self, stock_code: str) -> str:
        """分析同业比较"""
        try:
            import logging
            logging.info(f"开始分析股票{stock_code}的同业比较")

            # 获取当前股票的估值数据
            current_valuation = await stock_data_provider.get_stock_valuation_data(stock_code)
            logging.info(f"获取到的估值数据: {current_valuation}")

            if not current_valuation:
                logging.warning(f"无法获取股票{stock_code}的估值数据进行比较")
                return f"无法获取股票{stock_code}的估值数据进行比较"

            result = f"## 🔍 同业比较\n\n"

            pe = current_valuation.get('pe')
            pb = current_valuation.get('pb')
            logging.debug(f"PE: {pe}, PB: {pb}")

            if pe and pb:
                result += "- 当前估值指标：\n"
                result += f"  - 市盈率: {pe:.2f}\n"
                result += f"  - 市净率: {pb:.2f}\n\n"

                # 提供行业平均数据让大模型判断
                result += "- 同行业平均水平（参考数据）：\n"
                result += "  - 一般行业平均PE: 20-30倍\n"
                result += "  - 一般行业平均PB: 2-4倍\n\n"

                result += "- 同业比较分析：\n"
                result += "  - 比较当前估值与行业平均水平的差异\n"
                result += "  - 分析是否存在相对低估或高估的情况\n"
                result += "  - 考虑行业特征对估值的影响\n\n"

            else:
                result += "估值数据不足，无法进行同业比较\n"
                logging.warning("估值数据不足，无法进行同业比较")

            logging.info("成功生成同业比较分析结果")
            return result

        except Exception as e:
            self.logger.error(f"分析同业比较失败: {e}")
            return f"分析同业比较失败: {e}"

    async def _assess_fair_value_tool(self, stock_code: str) -> str:
        """评估公允价值（工具方法）"""
        try:
            import logging
            logging.info(f"开始评估股票{stock_code}的公允价值")

            result = f"## 🎯 估值结论\n\n"

            # 获取财务数据
            fundamental_data = await stock_data_provider.get_stock_fundamental_data(stock_code)
            valuation_data = await stock_data_provider.get_stock_valuation_data(stock_code)
            logging.info(f"获取到的财务数据: {fundamental_data}")
            logging.info(f"获取到的估值数据: {valuation_data}")

            if not fundamental_data or not valuation_data:
                logging.warning("数据不足，无法评估公允价值")
                return "数据不足，无法评估公允价值"

            # 简化的DCF模型评估
            try:
                profit_data = fundamental_data.get('profit_data', [])
                if profit_data:
                    latest_profit = profit_data[0]
                    net_profit = latest_profit.get('netProfit', 0)
                    logging.debug(f"最新净利润: {net_profit}")

                    if net_profit > 0:
                        # 简化的自由现金流计算
                        cashflow_data = fundamental_data.get('cashflow_data', [])
                        if cashflow_data:
                            latest_cashflow = cashflow_data[0]
                            operating_cashflow = latest_cashflow.get('operatingCashFlow', net_profit * 0.8)
                            logging.debug(f"经营现金流: {operating_cashflow}")

                            # 假设增长率和折现率
                            growth_rate = 0.05  # 5%增长率
                            discount_rate = 0.10  # 10%折现率

                            # 简化的DCF计算
                            terminal_value = operating_cashflow * (1 + growth_rate) / (discount_rate - growth_rate)
                            dcf_value = terminal_value / (1 + discount_rate) ** 5  # 5年期
                            logging.debug(f"DCF计算值: {dcf_value}")

                            current_price = valuation_data.get('current_price', 0)
                            if current_price > 0:
                                fair_value_ratio = dcf_value / current_price
                                logging.debug(f"公允价值比率: {fair_value_ratio}")

                                result += f"📈 DCF模型评估：\n"
                                result += f"  估计内在价值: {dcf_value:,.0f}\n"
                                result += f"  当前股价: {current_price:,.0f}\n"
                                result += f"  价值比率: {fair_value_ratio:.2f}\n\n"

                                if fair_value_ratio > 1.2:
                                    assessment = "显著低估（推荐买入）"
                                elif fair_value_ratio > 0.8:
                                    assessment = "估值合理"
                                else:
                                    assessment = "可能高估（谨慎持有）"

                                result += f"🎯 估值结论: {assessment}\n"
                                logging.info(f"DCF估值结论: {assessment}")
                            else:
                                result += "无法获取当前股价数据\n"
                                logging.warning("无法获取当前股价数据")
                        else:
                            result += "现金流数据不足\n"
                            logging.warning("现金流数据不足")
                    else:
                        result += "公司净利润为负，无法进行DCF评估\n"
                        logging.warning("公司净利润为负，无法进行DCF评估")
                else:
                    result += "财务数据不足\n"
                    logging.warning("财务数据不足")

            except Exception as calc_error:
                self.logger.error(f"DCF计算过程中出现错误: {calc_error}")
                result += f"DCF计算过程中出现错误: {calc_error}\n"

            logging.info("成功生成公允价值评估结果")
            return result

        except Exception as e:
            self.logger.error(f"评估公允价值失败: {e}")
            return f"评估公允价值失败: {e}"

    async def _calculate_valuation_score(self, valuation_ratios: Dict[str, float],
                                       historical_percentile: float, fair_value_assessment: str) -> float:
        """使用大模型计算估值面评分（0-10分）"""
        try:
            # 构建估值分析数据
            analysis_data = {
                "valuation_ratios": valuation_ratios,
                "historical_percentile": historical_percentile,
                "fair_value_assessment": fair_value_assessment
            }
            
            # 使用大模型进行评分
            scoring_prompt = self._get_valuation_scoring_prompt(analysis_data)
            llm_response = await self.llm.ainvoke(scoring_prompt)
            
            # 解析大模型响应
            scoring_result = self._parse_llm_scoring_response(llm_response)
            score = self._validate_and_clamp_score(scoring_result.get('score', 5))
            
            return score
            
        except Exception as e:
            self.logger.error(f"大模型估值面评分失败: {e}")
            # 降级到默认评分
            return 5.0

    async def _analyze_valuation_ratios(self, stock_code: str) -> Dict[str, float]:
        """分析估值比率"""
        try:
            valuation_data = await stock_data_provider.get_stock_valuation_data(stock_code)
            
            if not valuation_data:
                return {"pe": 0, "pb": 0, "ps": 0, "peg": 0, "dividend_yield": 0}
            
            # 提取主要估值比率 - 支持多种字段名
            ratios = {
                # 优先使用pe_ratio/pb_ratio，如果没有则使用pe/pb
                "pe": valuation_data.get('pe_ratio', valuation_data.get('pe', 0)),
                "pb": valuation_data.get('pb_ratio', valuation_data.get('pb', 0)),
                "ps": valuation_data.get('ps', 0),
                "peg": valuation_data.get('peg', 0),
                "dividend_yield": valuation_data.get('dividend_yield', 0)
            }
            
            # 如果PEG为0，尝试计算
            if ratios["peg"] == 0 and ratios["pe"] > 0:
                try:
                    # 简化的PEG计算：假设增长率为10%
                    ratios["peg"] = ratios["pe"] / 10.0
                except:
                    pass
            
            return ratios
            
        except Exception as e:
            self.logger.error(f"分析估值比率失败: {e}")
            return {"pe": 0, "pb": 0, "ps": 0, "peg": 0, "dividend_yield": 0}

    async def _assess_fair_value(self, stock_code: str) -> str:
        """评估公允价值水平"""
        try:
            valuation_data = await stock_data_provider.get_stock_valuation_data(stock_code)
            
            if not valuation_data:
                return "数据不足"
            
            pe = valuation_data.get('pe', 0)
            pb = valuation_data.get('pb', 0)
            
            # 简化的公允价值评估
            if pe > 0 and pb > 0:
                if pe < 15 and pb < 1.5:
                    return "显著低估"
                elif pe < 25 and pb < 2.5:
                    return "合理偏低"
                elif pe < 35 and pb < 3.5:
                    return "合理偏高"
                elif pe < 50 and pb < 5:
                    return "明显高估"
                else:
                    return "极度高估"
            else:
                return "估值数据不足"
                
        except Exception as e:
            self.logger.error(f"评估公允价值失败: {e}")
            return "评估失败"

    async def _calculate_historical_percentile(self, stock_code: str) -> float:
        """计算历史百分位"""
        try:
            # 简化的历史百分位计算
            # 在实际应用中，这里应该获取历史估值数据并计算百分位
            valuation_data = await stock_data_provider.get_stock_valuation_data(stock_code)
            
            if not valuation_data:
                return 50.0  # 默认中位数
            
            pe = valuation_data.get('pe', 0)
            
            # 基于PE的简化百分位估算
            if pe <= 0:
                return 50.0
            elif pe < 10:
                return 20.0  # 低估
            elif pe < 20:
                return 40.0  # 合理偏低
            elif pe < 30:
                return 60.0  # 合理偏高
            elif pe < 50:
                return 80.0  # 高估
            else:
                return 90.0  # 极度高估
                
        except Exception as e:
            self.logger.error(f"计算历史百分位失败: {e}")
            return 50.0

    def _calculate_valuation_confidence(self, valuation_ratios: Dict[str, float],
                                     data_quality: float = 0.5) -> float:
        """计算估值面分析置信度（0-1）"""
        confidence = 0.5  # 基础置信度
        
        # 数据完整性加分
        valid_ratios = sum(1 for ratio in valuation_ratios.values() if ratio > 0)
        if valid_ratios >= 3:
            confidence += 0.3
        elif valid_ratios >= 2:
            confidence += 0.2
        elif valid_ratios >= 1:
            confidence += 0.1
        
        # 数据质量加分
        confidence += data_quality * 0.2
        
        return round(min(confidence, 1.0), 2)

    def _generate_valuation_summary(self, score: float, valuation_ratios: Dict[str, float],
                                  fair_value_assessment: str, historical_percentile: float) -> str:
        """生成估值面摘要"""
        pe = valuation_ratios.get('pe', 0)
        pb = valuation_ratios.get('pb', 0)
        
        if score >= 8:
            return f"估值面极佳，PE{pe:.1f}倍PB{pb:.1f}倍显著低估，安全边际极高"
        elif score >= 6:
            return f"估值面良好，PE{pe:.1f}倍PB{pb:.1f}倍合理偏低，具备较好投资价值"
        elif score >= 4:
            return f"估值面平稳，PE{pe:.1f}倍PB{pb:.1f}倍估值合理，符合市场预期"
        elif score >= 2:
            return f"估值面一般，PE{pe:.1f}倍PB{pb:.1f}倍略偏高，需要谨慎评估"
        else:
            return f"估值面较差，PE{pe:.1f}倍PB{pb:.1f}倍明显高估，投资风险较高"

    def _get_valuation_scoring_prompt(self, analysis_data: Dict[str, Any]) -> str:
        """生成估值面评分prompt"""
        valuation_ratios = analysis_data.get("valuation_ratios", {})
        historical_percentile = analysis_data.get("historical_percentile", 50.0)
        fair_value_assessment = analysis_data.get("fair_value_assessment", "未知")
        
        prompt = f"""
        你是一个专业的股票估值分析师。请基于以下估值分析数据，给出0-10分的整数评分：

        估值分析数据：
        - 估值比率：
          PE: {valuation_ratios.get('pe', 0):.2f}
          PB: {valuation_ratios.get('pb', 0):.2f}
          PS: {valuation_ratios.get('ps', 0):.2f}
          PEG: {valuation_ratios.get('peg', 0):.2f}
          股息率: {valuation_ratios.get('dividend_yield', 0):.2f}%
        - 历史百分位: {historical_percentile:.1f}%
        - 公允价值评估: {fair_value_assessment}

        评分标准（严格使用0-10分制，不是百分制）：
        - 10分：估值极度低估，安全边际巨大，强烈推荐买入
        - 8-9分：估值显著低估，具备较好投资价值，建议买入
        - 6-7分：估值基本合理，投资价值一般，建议持有
        - 4-5分：估值偏高，投资风险增加，建议谨慎持有
        - 2-3分：估值显著高估，投资风险较大，建议减持
        - 0-1分：估值极度高估，强烈建议回避，建议卖出

        **重要提示：请严格返回0-10之间的评分，不要使用百分制（0-100）！**

        请严格按照以下JSON格式输出：
        {{
            "score": 0-10之间的整数或小数评分（例如：7、8.5等，不是70或85）,
            "reasoning": "详细的评分理由",
            "key_factors": ["关键因素1", "关键因素2", ...]
        }}

        注意：score字段必须是0-10范围内的数值，不是百分制！
        """
        
        return prompt

    def _parse_llm_scoring_response(self, llm_response: Any) -> Dict[str, Any]:
        """解析大模型评分响应"""
        try:
            # 尝试直接解析JSON
            if hasattr(llm_response, 'content'):
                content = llm_response.content
            else:
                content = str(llm_response)
            
            # 提取JSON部分
            json_match = re.search(r'\{.*\}', content, re.DOTALL)
            if json_match:
                json_str = json_match.group()
                result = json.loads(json_str)
                
                # 验证必需字段
                if 'score' in result:
                    return result
            
            # 如果JSON解析失败，尝试从文本中提取评分
            score_match = re.search(r'"score":\s*(\d+)', content)
            if score_match:
                score = int(score_match.group(1))
                return {
                    "score": score,
                    "reasoning": "从文本中提取的评分",
                    "key_factors": ["文本解析"]
                }
            
            # 如果都失败，返回默认值
            return {"score": 5, "reasoning": "解析失败，使用默认评分", "key_factors": ["解析失败"]}
            
        except Exception as e:
            self.logger.error(f"解析大模型响应失败: {e}")
            return {"score": 5, "reasoning": f"解析失败: {e}", "key_factors": ["解析错误"]}

    def _validate_and_clamp_score(self, score: Union[int, float]) -> int:
        """
        验证并限制评分在0-10范围内
        
        智能处理：
        - 自动检测百分制（0-100）并转换为十分制（0-10）
        - 对超出范围的评分进行合理限制
        - 提供详细的日志信息
        
        Args:
            score: 评分值（可能是整数、浮点数）
            
        Returns:
            0-10之间的整数评分
        """
        try:
            # 转换为浮点数
            score_float = float(score)
            
            # 智能检测：如果分数>10，可能是百分制，自动转换为十分制
            if score_float > 10:
                self.logger.warning(f"⚠️ 检测到百分制评分{score_float}，自动转换为十分制")
                score_float = score_float / 10.0
            
            # 转换为整数并限制在0-10范围内
            score_int = int(round(score_float))
            clamped_score = max(0, min(10, score_int))
            
            # 如果发生了限制，记录日志
            if score_int != clamped_score:
                self.logger.warning(f"⚠️ 评分{score_int}超出范围，已调整为{clamped_score}")
            
            return clamped_score
            
        except (ValueError, TypeError) as e:
            self.logger.warning(f"⚠️ 评分转换失败: {score}, 错误: {e}, 使用默认值5")
            return 5

    async def _generate_valuation_signals(self, stock_code: str, output_format: str = "text") -> Union[Dict[str, Any], str]:
        """生成估值信号，支持文本和JSON格式输出"""
        try:
            # 获取各项分析数据
            valuation_ratios = await self._analyze_valuation_ratios(stock_code)
            historical_percentile = await self._calculate_historical_percentile(stock_code)
            fair_value_assessment = await self._assess_fair_value(stock_code)
            
            # 计算评分和置信度
            valuation_score = await self._calculate_valuation_score(
                valuation_ratios, historical_percentile, fair_value_assessment
            )
            confidence = self._calculate_valuation_confidence(valuation_ratios)
            summary = self._generate_valuation_summary(
                valuation_score, valuation_ratios, fair_value_assessment, historical_percentile
            )
            
            # 根据输出格式返回结果
            if output_format == "json":
                return {
                    "dimension": "valuation",
                    "score": valuation_score,
                    "analysis": {
                        "valuation_ratios": valuation_ratios,
                        "fair_value_assessment": fair_value_assessment,
                        "historical_percentile": historical_percentile,
                        "summary": summary
                    },
                    "confidence": confidence,
                    "timestamp": pd.Timestamp.now().isoformat()
                }
            else:
                # 保持向后兼容的文本输出
                result = f"## ⭐ 估值面评分\n\n"
                
                # 显示估值指标
                result += "- 估值指标数据：\n"
                for ratio_name, ratio_value in valuation_ratios.items():
                    if ratio_value > 0:
                        result += f"  - {ratio_name.upper()}: {ratio_value:.2f}\n"
                result += "\n"
                
                # 显示分析结果
                result += f"- 公允价值评估: {fair_value_assessment}\n"
                result += f"- 历史百分位: {historical_percentile:.1f}%\n"
                result += f"- 估值面评分: {valuation_score}/10\n"
                result += f"- 分析置信度: {confidence:.2f}\n\n"
                
                result += f"- 估值面摘要: {summary}\n\n"
                
                # 获取其他分析结果用于文本输出
                peer_analysis = await self._analyze_peer_comparison(stock_code)
                fair_value_text = await self._assess_fair_value_tool(stock_code)
                
                result += "- 综合估值分析：\n"
                result += "  - 综合PE、PB等指标的估值水平\n"
                result += "  - 结合同业比较和公允价值评估\n"
                result += "  - 生成具体的投资信号和信心指数\n"
                result += "  - 提供明确的估值判断和投资建议\n\n"
                
                return result

        except Exception as e:
            error_msg = f"生成估值信号失败: {e}"
            if output_format == "json":
                return {
                    "error": error_msg,
                    "dimension": "valuation",
                    "score": 0.0,
                    "analysis": {
                        "valuation_ratios": {"pe": 0, "pb": 0, "ps": 0, "peg": 0, "dividend_yield": 0},
                        "fair_value_assessment": "分析失败",
                        "historical_percentile": 50.0,
                        "summary": error_msg
                    },
                    "confidence": 0.0,
                    "timestamp": pd.Timestamp.now().isoformat()
                }
            else:
                return error_msg


    async def generate_valuation_charts(self, stock_code: str) -> Dict[str, Any]:
        """
        生成估值分析可视化图表
        
        Args:
            stock_code: 股票代码
            
        Returns:
            图表生成结果
        """
        try:
            # 获取估值数据
            valuation_data = await stock_data_provider.get_stock_valuation_data(stock_code)
            if not valuation_data:
                return {"success": False, "error": "无法获取估值数据"}
            
            # 获取财务数据
            fundamental_data = await stock_data_provider.get_stock_fundamental_data(stock_code)
            if not fundamental_data:
                return {"success": False, "error": "无法获取财务数据"}
            
            # 构建财务比率数据
            ratios = {}
            
            # 提取主要估值比率
            if 'pe' in valuation_data:
                ratios['pe'] = valuation_data['pe']
            if 'pb' in valuation_data:
                ratios['pb'] = valuation_data['pb']
            if 'ps' in valuation_data:
                ratios['ps'] = valuation_data['ps']
            if 'pcf' in valuation_data:
                ratios['pcf'] = valuation_data['pcf']
            
            # 计算其他财务比率
            try:
                profit_data = fundamental_data.get('profit_data', [])
                balance_data = fundamental_data.get('balance_data', [])
                
                if profit_data and balance_data:
                    latest_profit = profit_data[0] if profit_data else {}
                    latest_balance = balance_data[0] if balance_data else {}
                    
                    # 计算ROE
                    net_profit = latest_profit.get('netProfit', 0)
                    total_equity = latest_balance.get('totalEquity', 0)
                    if total_equity > 0:
                        ratios['roe'] = net_profit / total_equity * 100
                    
                    # 计算资产负债率
                    total_assets = latest_balance.get('totalAssets', 0)
                    total_liability = latest_balance.get('totalLiability', 0)
                    if total_assets > 0:
                        ratios['debt_ratio'] = total_liability / total_assets * 100
                    
                    # 计算资产周转率
                    revenue = latest_profit.get('revenue', 0)
                    if total_assets > 0:
                        ratios['asset_turnover'] = revenue / total_assets
                    
                    # 计算现金流比率
                    cashflow_data = fundamental_data.get('cashflow_data', [])
                    if cashflow_data:
                        latest_cashflow = cashflow_data[0] if cashflow_data else {}
                        operating_cashflow = latest_cashflow.get('operatingCashFlow', 0)
                        if net_profit > 0:
                            ratios['cash_flow_ratio'] = operating_cashflow / net_profit
            
            except Exception as calc_error:
                self.logger.warning(f"计算财务比率时出错: {calc_error}")
            
            # 生成财务比率雷达图
            radar_chart = None
            if ratios:
                # 返回图表数据字典，不调用visualizer
                radar_chart = {
                    'type': 'financial_ratios_radar',
                    'stock_code': stock_code,
                    'title': f"{stock_code} 财务比率雷达图",
                    'data': ratios
                }
            
            # 生成估值指标对比图
            if 'pe' in valuation_data or 'pb' in valuation_data:
                # 创建估值指标对比数据
                valuation_metrics = []
                if 'pe' in valuation_data:
                    valuation_metrics.append({
                        'name': '市盈率(PE)',
                        'value': valuation_data['pe'],
                        'industry_avg': 20.0  # 假设行业平均
                    })
                if 'pb' in valuation_data:
                    valuation_metrics.append({
                        'name': '市净率(PB)',
                        'value': valuation_data['pb'],
                        'industry_avg': 2.5  # 假设行业平均
                    })
                if 'ps' in valuation_data:
                    valuation_metrics.append({
                        'name': '市销率(PS)',
                        'value': valuation_data['ps'],
                        'industry_avg': 3.0  # 假设行业平均
                    })
                
                # 显示估值指标对比图
                if valuation_metrics:
                    await self._display_valuation_comparison_chart(stock_code, valuation_metrics)
            
            return {
                "success": True,
                "charts_generated": ["financial_ratios_radar", "valuation_comparison"],
                "message": "估值分析图表生成完成"
            }
            
        except Exception as e:
            self.logger.error(f"生成估值分析图表失败: {e}")
            return {"success": False, "error": str(e)}
    
    async def _display_valuation_comparison_chart(self, stock_code: str, valuation_metrics: List[Dict[str, Any]]):
        """显示估值指标对比图"""
        try:
            import plotly.graph_objects as go
            
            # 提取数据
            metric_names = [metric['name'] for metric in valuation_metrics]
            current_values = [metric['value'] for metric in valuation_metrics]
            industry_avgs = [metric['industry_avg'] for metric in valuation_metrics]
            
            # 创建对比图
            fig = go.Figure()
            
            # 添加当前值柱状图
            fig.add_trace(go.Bar(
                name='当前值',
                x=metric_names,
                y=current_values,
                marker_color='#1f77b4'
            ))
            
            # 添加行业平均值柱状图
            fig.add_trace(go.Bar(
                name='行业平均',
                x=metric_names,
                y=industry_avgs,
                marker_color='#ff7f0e'
            ))
            
            # 更新布局
            fig.update_layout(
                title=f"{stock_code} 估值指标对比",
                xaxis_title="估值指标",
                yaxis_title="数值",
                barmode='group',
                height=400
            )
            
            # 创建Plotly元素
            elements = [
                cl.Plotly(
                    name=f"{stock_code} 估值对比",
                    figure=fig,
                    display="inline"
                )
            ]
            
            # 发送消息
            await cl.Message(
                content=f"### {stock_code} 估值指标对比分析",
                elements=elements
            ).send()
            
        except Exception as e:
            self.logger.error(f"显示估值对比图失败: {e}")


# 全局实例
stock_valuation_analysis_agent = StockValuationAnalysisAgent()